/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import documentweighting.BM25;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import queryprocessing.QueryExpansion;
import queryprocessing.Tokenizer;
import queryterm.QueryTerm;
import retrieval.ListDocument;
import retrieval.RetrieveTerm;
import util.FileListing;
import util.Timer;

/**
 *
 * @author Danang
 */
public class MessageRetrieval {
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        if (args.length<4) {
            throw new Exception("Argument must be : <Index_Dir> <Use_Compressed_Inverted_File> <Query_File> <NTopRanked>");
        }
        int nTopRanked = Integer.parseInt(args[3]);
        String rootDir = args[0];
        if (!rootDir.endsWith("/")) {
            rootDir += "/";
        }
        String inputQueryFile = args[2];
        boolean useCompression = args[1].contentEquals("1");
        System.out.println("Index file in "+rootDir);
        System.out.println("Query file in "+inputQueryFile);
        System.out.println("Use compressed inverted file "+useCompression);
        System.out.println("Print "+nTopRanked+" search results.");
        // reading file input query
        HashMap<String,String> queries = new HashMap<String, String>();
        BufferedReader br = new BufferedReader(new FileReader(new File(inputQueryFile)));
        String in;
        while ((in=br.readLine())!=null) {
            if (!in.isEmpty()) {
                String[] split = in.split(" = ");
                if (split.length!=2) {
                    throw new Exception("Error : input query must be Qn<space>=<space>Query");
                }
                queries.put(split[0], split[1]);
            }
        }
        br.close();
        
        // read statistic file Jumlah dokumen, Panjang Rata-rata Dokumen
        FileListing statistic = new FileListing();
        statistic.readStatisticFile(rootDir);
        
        ListDocument retrieveDocuments = new ListDocument();
        retrieveDocuments.setDocumentStatistic(statistic.getJumlahMail(), statistic.getAverageLengthMail());
//        statistic.initReadNestedIndexFileList(rootDir); // uncomment jika menggunakan normalisasi dokumen
//        retrieveDocuments.initReadDocumentLength(statistic);
        
        // Parameter weighting
        double k1 = 1.2, k2 = 100, b = 0; // Jika pakai normalisasi b = 0.75
        
        // inisialisasi object pencari
        RetrieveTerm rt = new RetrieveTerm(rootDir, useCompression);
        System.out.println("Starting to search all queries");
        Timer all_search_time = new Timer();
        Iterator iter = queries.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry pairs = (Map.Entry) iter.next();
            String query_number = (String) pairs.getKey();
            String query = (String) pairs.getValue();
            // inisialisasi timer
            Timer t = new Timer();
            
            // pre proses query : tokenizer
            ArrayList<QueryTerm> listQuery = Tokenizer.tokenize(query);
            // pre proses query : query expansion
            listQuery = QueryExpansion.expand(listQuery);
            QueryExpansion.sortListQuery(listQuery);
            // search query
            for (QueryTerm qt : listQuery) {
                if (qt.getIsOneWord()) {
                    rt.searchToken(qt.getToken(), qt.getField(), retrieveDocuments);
                } else {
                    retrieveDocuments.addQueryBerurutan(qt.getToken(), qt.getField());
                }
            }
            // hitung bobot dokumen yang ter-retrieve
            BM25 hitungBobot = new BM25(listQuery, retrieveDocuments);
            if (hitungBobot.isIsQueryFound()) {
                hitungBobot.getBM25Weight(k1, k2, b, listQuery, retrieveDocuments);

                // catat waktu eksekusi
                String waktu = t.printExecution_timeOnly();
                System.out.println("Finished search query "+query+" in "+waktu);

                // print ke file output ZD-Qn.txt
                String nama_file = query_number;
                File outputFile = new File("ZD-"+nama_file+".txt");
                BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
                bw.write(retrieveDocuments.toOutputFile(query_number, nTopRanked));
                bw.write(waktu);
                bw.close();

//                 output 2 : statistik hasil search
                File outputFile2 = new File("output-"+nama_file);
                BufferedWriter bw2 = new BufferedWriter(new FileWriter(outputFile2));
                bw2.write(retrieveDocuments.toString());
                bw2.write(waktu);
                bw2.close();
            } else {
                System.out.println("Query "+query+" not found.");
            }
        }
        
        // close all resource files
        rt.closeAllFiles();
//        statistic.closeReaderNestedIndex(); // uncomment jika menggunakan normalisasi dokumen
        
        all_search_time.printExecution_time("Finished search all queries.");
    }
}
